package com.fruit.account.service.useractivity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fruit.mapper.account.repeat.ActivityRepeatDetailMapper;
import com.fruit.pojo.promotion.ActivityRule;
import com.fruit.pojo.promotion.ActivityUserInfo;
import com.fruit.sdk.account.useractivity.UserActivityService;
import com.fruit.util.ResultInfo;
import com.fruit.util.ResultUtil;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
 * 活动用户圆梦相关Service
 *
 * @author Administrator
 * @version 2018.01.08 10:16
 */
@Slf4j
@Service("userActivityService")
public class UserActivityServiceImpl implements UserActivityService {
	@Autowired
	private ActivityRepeatDetailMapper activityRepeatDetailMapper;
	@Data 
	class PointRule { 
		private BigDecimal leveKey = null; //见点档次
		private BigDecimal ratio = null; //见点比率
		private Map<String,String> ratLimitMap = new HashMap<>(); //见点上限集合
		private String[] repPoints = null; // 复投点儿
	}
	
	@Override
	public Map<String, Object> checkUserActivityInfos(String tradeId, Integer userId, String code) {
		log.info("[{}]---【校验用户是否参与活动】---【开始params】---userId={},code={}", tradeId, userId, code);
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			if (userId == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "传入参数用户id不能为空!"));
				return result;
			}
			if (StringUtils.isEmpty(tradeId)) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "日志流水号不能为空!"));
				return result;
			}
			if (StringUtils.isEmpty(code)) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "活动编码不能为空!"));
				return result;
			}
			// 获取活动规则
			log.info("[{}]---【校验用户是否参与活动】---【获取活动规则】-----", tradeId);
			// 获取用户活动累计信息
			Map<String, Object> pm = new HashMap<String, Object>();
			pm.put("code", code);
			pm.put("userId", userId);
			ActivityUserInfo acUser = activityRepeatDetailMapper.getActivityUserInfoByCode(pm);
			if (acUser == null) {
				log.info("【校验用户是否参与活动】---【获取用户活动累计信息为null】-----userId={}",userId);
				result.put("flag", 0);
			} else {
				log.info("【校验用户是否参与活动】-----userId={},activityId={}", userId, acUser.getActivityId());
				result.put("flag", 1);
			}
			result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "SUCCESS", "操作成功!"));
		} catch (Exception e) {
			log.error("[" + tradeId + "]---【校验用户是否参与活动】---【异常】-----{}", e);
			result.put("result",ResultUtil.initResult(ResultInfo.ERROR, "exception", "校验用户是否参与活动处理异常！"));
		}
		log.info("【校验用户是否参与活动】---【结束】---{}", result.toString());
		return result;
	}

	@Override
	public Map<String, Object> getUserActivityInfos(String tradeId, Integer userId, String code) {
		log.info("[{}]---【获取用户圆梦相信息】---【开始params】---userId={},code={}", tradeId, userId, code);
		Map<String, Object> result = new HashMap<String, Object>();
		try {
			if (userId == null) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "传入参数用户id不能为空!"));
				return result;
			}
			if (StringUtils.isEmpty(tradeId)) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "日志流水号不能为空!"));
				return result;
			}
			if (StringUtils.isEmpty(code)) {
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "param_error", "活动编码不能为空!"));
				return result;
			}
			// 获取活动规则
			log.info("[{}]---【获取用户圆梦相信息】---【获取活动规则】-----", tradeId);
			Map<String, Object> parm = new HashMap<String, Object>();
			parm.put("code", code);
			List<ActivityRule> ruleList = activityRepeatDetailMapper.selectActivityRulesByCode(parm);
			if (ruleList == null || ruleList.size() <= 0) {
				log.info("[" + tradeId + "]---【获取用户圆梦相信息】---【获取活动规则】-----【结果为null】");
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "获取活动规则失败!"));
				return result;
			}
			Map<String,PointRule> indirectMap = new HashMap<>(); //见点档次集合
			for (ActivityRule ru : ruleList) {
				if ("17".equals(ru.getCondition())) { // 见点档次
					if(StringUtils.isEmpty(ru.getValue())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点档次规则有误!"));
						return result;
					}
					if(StringUtils.isEmpty(ru.getReserve1())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点上限集合规则有误!"));
						return result;
					}
					if(StringUtils.isEmpty(ru.getReserve2())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点复投断点设置规则有误!"));
						return result;
					}
					if(StringUtils.isEmpty(ru.getReserve3())){
						result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "见点比率设置规则有误!"));
						return result;
					}
					PointRule pr = new PointRule();
					pr.setLeveKey(new BigDecimal(ru.getValue()));
					pr.setRatio(new BigDecimal(ru.getReserve3()).divide(new BigDecimal(100))); //设置比率
					String[] liAyy = ru.getReserve1().split(",");
					for(String str : liAyy){
						String[] keyValue = str.split("=");
						if(keyValue.length == 2){
							pr.getRatLimitMap().put(keyValue[0], keyValue[1]); // 设置见点上限集合							
						} else {
							result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "rule_error", "设置见点上限集合失败，见点档次规则有误!"));
							return result;
						}
					}
					pr.setRepPoints(ru.getReserve2().split(",")); //设置隔断点
					indirectMap.put(ru.getValue(), pr);
				}
			}
			
			PointRule curPointRule = null; //该用户见点档次
			BigDecimal pointLimit = BigDecimal.ZERO ; // 该用户见点上限
			
			// 获取用户活动累计信息
			Map<String, Object> pm = new HashMap<String, Object>();
			pm.put("code", code);
			pm.put("userId", userId);
			ActivityUserInfo acUser = activityRepeatDetailMapper.getActivityUserInfoByCode(pm);
			if (acUser == null) {
				log.info("【获取用户圆梦相信息】---【获取用户活动累计信息为null】-----userId={}",userId);
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "addUser_error", "获取用户活动累计信息为null"));
				return result;
			}
			List<String> dList = new ArrayList<>(indirectMap.keySet()); //构建档次集合
			Collections.sort(dList); // 默认升序
			
			BigDecimal addConsume = acUser.getAddConsume() == null ? BigDecimal.ZERO : acUser.getAddConsume();
			BigDecimal addRepeat = acUser.getAddRepeat() == null ? BigDecimal.ZERO : acUser.getAddRepeat();
			BigDecimal total = addConsume.add(addRepeat);
			String curPointRuleKey = getMidNumber(total, dList); //获取档次区间
			log.info("【获取用户圆梦相信息】---【获取用档次key】---curPointRuleKey={}", curPointRuleKey);
			if (StringUtils.isEmpty(curPointRuleKey)) {
				log.info("【获取用户圆梦相信息】---【获取用档次key为空】---");
				result.put("leve", 0);
				result.put("rate", "0.00%");
				result.put("limit", "0元");
				result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "addUser_success", "获取用档次key不在区间内!"));
				return result;
			}
			curPointRule = indirectMap.get(curPointRuleKey);
			if (curPointRule == null) {
				log.info("【获取用户圆梦相信息】---【获取用户档次结果为null】-----userid={},addConsume={},addRepeat={}", userId,acUser.getAddConsume(),acUser.getAddRepeat());
				result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "addUser_error", "获取用户档次失败!"));
				return result;
			} else {
				log.info("【获取用户圆梦相信息】---【获取用户档次】---Ratio={}", curPointRule.getRatio());
				//获取用户见点上限，根据用户直推下级人数已经下级的复投次数
				Map<String, Object> acMap = new HashMap<>();
				acMap.put("type", "00");
				acMap.put("userId", userId);
				acMap.put("code", code);
				List<ActivityUserInfo> acList = activityRepeatDetailMapper.getActivityUserAccInfoByCode(acMap);
				String curKey = getRatLimitKey(acList, curPointRule);
				log.info("【获取用户圆梦相信息】---【获取用户档次见点上限key】---curKey={}", curKey);
				if(StringUtils.isEmpty(curKey)) {
					result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "curPointRuleKey_error", "获取用户见点上限key异常!", "", "01"));
					return result;
				}
				String pointLimitValue = curPointRule.getRatLimitMap().get(curKey); // 设置该用户见点上限
				log.info("【获取用户圆梦相信息】---【获取用户档次见点上限值为】---pointLimitValue={}", pointLimitValue);
				if(StringUtils.isEmpty(pointLimitValue)) {
					result.put("result", ResultUtil.initResult(ResultInfo.ERROR, "curPointRule_error", "获取用户见点上限异常!", "", "01"));
					return result;
				}
				pointLimit = new BigDecimal(pointLimitValue);
			}
			int leve = 0;
			for (int i = 0; i < dList.size(); i++) {
				if(dList.get(i).equals(curPointRuleKey)) {
					leve = i+1;
				}
			}
			if(leve > 0) {
				result.put("leve", "V" + leve);
			} else {
				result.put("leve", leve);
			}
			result.put("rate", curPointRule.getRatio().multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_DOWN) + "%");
			if(pointLimit.compareTo(new BigDecimal(10000)) < 0) {
				result.put("limit", pointLimit.stripTrailingZeros().toPlainString()+ "元");
			} else {
				result.put("limit", pointLimit.divide(new BigDecimal(10000)).stripTrailingZeros().toPlainString() + "万元");
			}
			
			result.put("result", ResultUtil.initResult(ResultInfo.SUCCESS, "success", "操作成功"));
		} catch (Exception e) {
			log.error("[" + tradeId + "]---【获取用户圆梦相信息】---【异常】-----{}", e);
			result.put("result",ResultUtil.initResult(ResultInfo.ERROR, "exception", "获取用户圆梦相信息处理异常！"));
		}
		log.info("【获取用户圆梦相信息】---【结束】---{}", result.toString());
		return result;
	}
	
	/**
	 * 返回当前档次规则的见点上限key
	 * @param list 用户复投集合
	 * @param curPointRule 当前规则
	 * @return String 见点上限key
	 */
	public String getRatLimitKey(List<ActivityUserInfo> list, PointRule curPointRule) {
		StringBuffer result = new StringBuffer();
		List<String> poins = Arrays.asList(curPointRule.getRepPoints());
		log.info("【当前用户见点规则】---【当前规则断点集合】---{}", poins.toString());
		Collections.sort(poins); // 默认升序
		if(list == null || list.size() == 0) {
			result.append("N0N0");
			log.info("【当前用户见点规则】---【获取用户见点上限】---key=N0N0");
			
		} else if(list.size() == 1) {
			ActivityUserInfo af = list.get(0);
			log.info("【当前用户见点规则】---【获取用户见点上限】---repeatNumber={}", af.getRepeatNumber());
			String res = getMidNumber(new BigDecimal(af.getRepeatNumber()), poins);
			log.info("【当前用户见点规则】---【获取用户见点上限】---【区间值】---{}", res);
			result.append("N0");
			if(StringUtils.isEmpty(res)) {
				result.append("N1");
			} else {
				result.append("P" + res.trim());
			}
		} else {
			List<String> st = new ArrayList<>();
			for (int i = 0; i < list.size(); i++) {
				if(i == 2) {
					break;
				}
				StringBuffer tmp = new StringBuffer();
				ActivityUserInfo a1 = list.get(i);
				log.info("【当前用户见点规则】---【获取用户见点上限】---【first】---repeatNumber={}", a1.getRepeatNumber());
				String res = getMidNumber(new BigDecimal(a1.getRepeatNumber()), poins);
				log.info("【当前用户见点规则】---【获取用户见点上限】---【区间值】---{}", res);
				if(StringUtils.isEmpty(res)) {
					tmp.append("N1");
				} else {
					tmp.append("P" + res.trim());
				}
				st.add(tmp.toString());
			}
			Collections.sort(st);
			result.append(st.get(0)).append(st.get(1));
		}
		log.info("【当前用户见点规则】---【key】---{}", result.toString());
		return result.toString();
	}
	
	/**
	 * 返回key所在区间的起始值
	 * @param key 值
	 * @param list 集合
	 * @return 区间起始值
	 */
	public String getMidNumber(BigDecimal key,List<String> list){
		String result = null;
		log.info("【返回key所在区间的起始值】---【开始】---key={},list={}-----", key, list.toString());
		if(list.size() == 1) {
			if(key.compareTo(new BigDecimal(list.get(0))) < 0) {
				return result;
			}else {
				result = list.get(0);
				return result;
			}
		}
		for(int j=0; j < list.size() - 1; j++) {
			if(key.compareTo(new BigDecimal(list.get(j))) < 0) {
				break;
			}
			if(key.compareTo(new BigDecimal(list.get(list.size() - 1))) >= 0) {
				result = list.get(list.size() - 1);
				break;
			}
			if(key.compareTo(new BigDecimal(list.get(j))) >= 0 && key.compareTo(new BigDecimal(list.get(j+1))) < 0) {
				result = list.get(j);
				break;
			}
		}
		log.info("【返回key所在区间的起始值】---【result】---", result);
		return result;
	}
}
